/** \file    MergeSegmentation.h
  * \brief   (template) operations combining several segments into one.
  * \date    2002
  * \author  Fedor Chelnokov
  * \version $Header: /home/cscom1r4/cvsroot/cs/include/segm/MergeSegmentation.h,v 1.2 2005/04/04 04:10:16 cscom1r4 Exp $
  */

#ifndef _MergeSegmentation_h_
#define _MergeSegmentation_h_

#include "Segmentation.h"
#include "xtd/group.h"

#define NEW_IND(k)	(newSegmentIndeces[xtd::find_root_idx(c, (k))])

template <class C>
void Segmentation::merge(C& c)
{
	assert(c.size() == count());
	size_t size = c.size();

	//indeces of segments that a given segment will be main part of
	IntArr newSegmentIndeces(count(), -1);
	size_t i;
	segmentIvector newSegments;
	for (i = 0; i != size; ++i) {
		if (c[i].is_root()) {
			size_t new_segm_i = newSegments.size();
			newSegmentIndeces[i] = 
				newSegments.insert(Segment(m_segmentIvector[i].color, c[i].pixels));
		}
	}

	//rewrite index map
	YATL::Arr2i::iterator k;
	for( k = m_segmentCoordMap.begin(); k != m_segmentCoordMap.end(); ++k ) {
		if (*k == -1) 
			continue;
		*k = NEW_IND(*k);
	}

	for (i = 0; i != size; ++i) {
		int ni = NEW_IND(i);
		IntIntMap::iterator j;
		for( j = m_segmentIvector[i].neighbours.begin(); j != m_segmentIvector[i].neighbours.end(); ++j ) {
			int nj = NEW_IND(j->second);
			newSegments[ni].neighbours[color2int(newSegments[nj].color)] = nj;
		}
	}
	m_segmentIvector.swap(newSegments);
	changed();
}

#undef NEW_IND

#endif //_MergeSegmentation_h_
